using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections;

namespace HBM2DLL
{
    public partial class main : Form
    {
        public main()
        {
            InitializeComponent();
        }

        private void cmdOpenFolder_Click(object sender, EventArgs e)
        {                        
            opFile.ShowDialog();
            string fileName = opFile.FileName;
            string content = System.IO.File.ReadAllText(fileName);
            HBM2DLL(content);

        }

        private string HBM2DLL(string content)
        {
            string _tableName;
            IList _listColumn = new ArrayList();
            string strRegTable = "<class[^>]*table=\"([^\"]*)\"";
            string strRegColumn4 = "<property[^>\"]*\"([^\"]*)\"[^>\"]*\"([^\"]*)\"[^>\"]*\"([^\"]*)\"[^>\"]*\"([^\"]*)\"";
            string strRegColumn3 = "<property[^>\"]*\"([^\"]*)\"[^>\"]*\"([^\"]*)\"[^>\"]*\"([^\"]*)\"[^>\"]*";
            string strReferenceKey = "<many-to-one[^>\"]*\"[^\"]*\"[^>\"]*\"([^\"]*)\"[^>\"]*\"([^\"]*)\"[^>\"]*";
            string strTableReference = "([^.,]*),";
            RegexOptions optionRegx = RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase;
            Regex regxTable = new Regex(strRegTable, optionRegx);
            Match matchTable = regxTable.Match(content);
            _tableName = matchTable.Groups[1].Value;
            _listColumn = new ArrayList();
            Regex regxColumn = new Regex(strRegColumn4, optionRegx);
            MatchCollection matchCollection = regxColumn.Matches(content);
            foreach (Match match in matchCollection)
            {
                Column cl = new Column();
                cl.Name = match.Groups[1].Value;
                cl.Type = match.Groups[2].Value;
                cl.Length = match.Groups[4].Value;
                cl.ReferenceTable = string.Empty;
                _listColumn.Add(cl);
            }
            // 3 column
            Regex regxColumn3 = new Regex(strRegColumn3, optionRegx);
            MatchCollection matchCollection3 = regxColumn3.Matches(content);
            foreach (Match match in matchCollection3)
            {
                Column cl = new Column();
                cl.Name = match.Groups[1].Value;
                cl.Type = match.Groups[2].Value;
                cl.Length = string.Empty;
                bool checkAdd = true;
                foreach (Column tem in _listColumn)
                {
                    if (cl.Name.Equals(tem.Name))
                    {
                        checkAdd = false;
                        break;
                    }
                }
                cl.ReferenceTable = string.Empty;
                if (checkAdd)
                    _listColumn.Add(cl);
            }
            Regex regxColumnRefer = new Regex(strReferenceKey, optionRegx);
            MatchCollection matchCollectionRefer = regxColumnRefer.Matches(content);
            foreach (Match match in matchCollectionRefer)
            {
                Column cl = new Column();
                cl.Name = match.Groups[1].Value;
                Regex regTableRefer = new Regex(strTableReference, optionRegx);
                Match matchTableRefer = regTableRefer.Match(match.Groups[2].Value);
                cl.Type = "Int";
                cl.ReferenceTable = matchTableRefer.Groups[1].Value;
                _listColumn.Add(cl);
            }
            //label1.Text = "Complete";            
            System.IO.File.WriteAllText(@"C:\" + _tableName + ".txt", CreateTable(_tableName, _listColumn));            
            return CreateTable(_tableName, _listColumn);
        }
        protected string CreateTable(string tableName, IList columnCollection)
        {
            string strDDL = string.Empty;
            strDDL += "CREATE TABLE " + tableName+"\n(\n";
            strDDL += " [Id] INT PRIMARY KEY IDENTITY(1,1),\n";
            int numberColumn = columnCollection.Count;
            int i = 1;
            string append = ",";
            foreach(Column cl in columnCollection)
            {
                
                if (i == numberColumn)
                {
                    append = string.Empty;
                }
                if (!string.IsNullOrEmpty(cl.ReferenceTable))
                {
                    strDDL += " [" + cl.Name + "] INT references " + cl.ReferenceTable + "(ID) " + append + "\n";
                }
                else if (!string.IsNullOrEmpty(cl.Length))
                {
                    strDDL += " [" + cl.Name + "] " + GetDatabaseType(cl.Type) + "(" + cl.Length + ")" + append + "\n";
                }
                else
                {
                    strDDL += " [" + cl.Name + "] " + GetDatabaseType(cl.Type) + " " + append + "\n";
                }
                i++;
            }
            strDDL += ")\n";
            return strDDL;
        }

        protected string GetDatabaseType(string type)
        {
            string strType = type.ToLower();
            switch (strType)
            { 
                case "int32":
                case "int16":
                    return "int";
                case "string":
                    return "nvarchar";
                case "bool":
                    return "bit";
                case "boolean":
                    return "bit";
                case "double":
                    return "float";
                default:
                    return strType;
            }
        }

        private void cmdOpenFolderDic_Click(object sender, EventArgs e)
        {
            opFolder.ShowDialog();
            string strDirector = opFolder.SelectedPath;
            string [] fileList = System.IO.Directory.GetFiles(strDirector);
            string strDDL = string.Empty;
            foreach (string str in fileList)
            {
                if (str.ToLower().EndsWith(".hbm.xml"))
                {
                    strDDL += HBM2DLL(System.IO.File.ReadAllText(str));
                }
            }
            txtQuery.Text = strDDL;
            txtQuery.WordWrap = true;
        }

        private void opFolder_HelpRequest(object sender, EventArgs e)
        {

        }
        
    }

    public class Column
    {
        string _name;
        string _type;
        string _length;
        string _referenceTable;
        public string Name
        {
            set { _name = value; }
            get { return _name; }
        }
        public string Type
        {
            set { _type = value; }
            get { return _type; }
        }
        public string Length
        {
            set { _length = value; }
            get { return _length; }
        }
        public string ReferenceTable
        {
            set { _referenceTable = value; }
            get { return _referenceTable; }
        }
    }
}